package com.apop.accompany.bussiness.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.apop.accompany.bussiness.mapper.MenuMapper;
import com.apop.accompany.bussiness.model.entity.Menu;
import com.apop.accompany.bussiness.model.vo.MenuVo;
import com.apop.accompany.bussiness.service.IMenuService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class MenuServiceImpl implements IMenuService {

    @Resource
    MenuMapper menuMapper;

    @Override
    public List<Menu> getAvailableMenu(){
        List<Menu> list = menuMapper.availableMenu();
        return list;
    }

    @Override
    public List<MenuVo> getAvailableMenuVo() {
        List<Menu> list = menuMapper.availableMenu();
        List<MenuVo> voList = convertToMenuVo(list);
        return voList;
    }

    // 单个 Menu 转换为 MenuVo
    private MenuVo convertToMenuVo(Menu menu) {
        MenuVo menuVo = new MenuVo();
        BeanUtil.copyProperties(menu, menuVo); // 使用 BeanUtil 复制属性
        menuVo.setLabel(menu.getName());
        // meta 转 map
        if (!menu.getMetaJson().isEmpty()){
            // 使用 FastJSON 将 JSON 转换为 Map
            Map<String, Object> map = JSON.parseObject(menu.getMetaJson(), new TypeReference<Map<String, Object>>(){});
            menuVo.setMeta(map);
        }

        return menuVo;
    }

    // 将 Menu 转换为 MenuVo 并设置 children
    public List<MenuVo> convertToMenuVo(List<Menu> menus) {
        // 先将所有 Menu 转换为 MenuVo
        Map<Integer, MenuVo> menuMap = menus.stream()
                .map(this::convertToMenuVo)
                .collect(Collectors.toMap(MenuVo::getId, vo -> vo));

        // 构建树结构
        List<MenuVo> rootMenuVos = new ArrayList<>();
        for (MenuVo menuVo : menuMap.values()) {
            if ( menuVo.getParentId() == null || menuVo.getParentId() == 0) {
                rootMenuVos.add(menuVo);
            } else {
                MenuVo parent = menuMap.get(menuVo.getParentId());
                if (parent != null && parent.getChildren() == null) {
                    parent.setChildren(new ArrayList<>());
                }
                if (parent != null) {
                    parent.getChildren().add(menuVo);
                }
            }
        }

        return rootMenuVos;
    }
}
